package com.ashlikun.pdfview.renderer

import android.content.Context
import android.graphics.Bitmap
import android.graphics.RectF
import android.graphics.pdf.PdfRenderer
import android.util.Size
import com.ashlikun.pdfview.PDFViewConfig
import com.ashlikun.pdfview.model.PdfBookmark
import com.ashlikun.pdfview.model.PdfLink
import com.ashlikun.pdfview.model.PdfMeta
import com.ashlikun.pdfview.source.DocumentSource
import com.ashlikun.pdfview.util.PdfViewUtil
import java.io.IOException

/**
 * 作者　　: 李坤
 * 创建时间: 2024/7/3　13:41
 * 邮箱　　：496546144@qq.com
 *
 *
 * 功能介绍：Android 官方的渲染器
 */
class PdfSystemRenderer(private val context: Context, private val config: PDFViewConfig) : IPdfRenderer {
    var pdfRenderer: PdfRenderer? = null
    private val densityDpi: Int

    //缓存Page，不用系统的，加快打开速度
    private val pages = HashMap<Int, PdfRenderer.Page>()

    init {
        densityDpi = context.resources.displayMetrics.densityDpi
    }

    fun openPageSystem(pageIndex: Int): PdfRenderer.Page {
        //这里不能打开，系统的渲染器只能打开一页，用完需要关闭
        synchronized(pages) {
            if (!pages.containsKey(pageIndex)) {
                val page = pdfRenderer!!.openPage(pageIndex)
                pages[pageIndex] = page
            }
        }
        return pages[pageIndex]!!
    }

    fun closePage(page: PdfRenderer.Page) {
        //反射 pdfRenderer私有字段mCurrentPage，反射的速度比close快
        try {
            val field = PdfRenderer::class.java.getDeclaredField("mCurrentPage")
            field.isAccessible = true
            field[pdfRenderer] = null
        } catch (e: Exception) {
            //无法反射，清除缓存
            synchronized(pages) { pages.remove(page!!.index) }
            e.printStackTrace()
            page!!.close()
        }
    }

    @Throws(IOException::class)
    override fun createRenderer(docSource: DocumentSource, password: String?) {
        pdfRenderer = docSource.create(context, this, password) as PdfRenderer
    }

    override fun renderPage(bitmap: Bitmap, pageIndex: Int, width: Int, height: Int, annotationRendering: Boolean) {
        if (PdfViewUtil.DEBUG_MODE) PdfViewUtil.logi("renderPage start pageIndex = " + pageIndex + "  width = " + bitmap!!.width + "    height" + bitmap.height)
        val page = openPageSystem(pageIndex)
        page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
        if (PdfViewUtil.DEBUG_MODE) PdfViewUtil.logi("renderPage end pageIndex = $pageIndex")
        //渲染完毕关闭,如果能反射就不用关闭了
        closePage(page)
    }

    override val pageCount: Int
        get() = pdfRenderer!!.pageCount

    override fun getPageSize(pageIndex: Int): Size {
        //这里只能打开这页才能获取宽高
        val page = openPageSystem(pageIndex)
        var width = page.width
        var height = page.height
        val size =  Size(width, height)
        //必须关闭
        closePage(page)
        if (PdfViewUtil.DEBUG_MODE) PdfViewUtil.logi("getPageSize   pageIndex = $pageIndex  width = ${size.width}    height${size.height}   densityDpi = $densityDpi")
        return size
    }

    override fun openPage(pageIndex: Int) {
        //这里不能打开，系统的渲染器只能打开一页，用完需要关闭
        synchronized(pages) {
            if (!pages.containsKey(pageIndex)) {
                pages[pageIndex] = pdfRenderer!!.openPage(pageIndex)
            }
        }
    }

    override val metaData: PdfMeta
        get() = PdfMeta()
    override val bookmarks: List<PdfBookmark>
        get() = ArrayList()

    override fun getPageLinks(docPage: Int): List<PdfLink> {
        return ArrayList()
    }

    override fun mapRectToDevice(docPage: Int, startX: Int, startY: Int, sizeX: Int, sizeY: Int, i: Int, rect: RectF): RectF {
        return RectF()
    }

    override fun close() {
        pdfRenderer!!.close()
    }
}
